package com.quanquan.store.controller;

import base.BaseController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.quanquan.store.configBean.RabbitSender;
import com.quanquan.store.dto.KetopParkingRecordDTO;
import com.quanquan.store.dto.KetopVipDTO;
import com.quanquan.store.entity.GroupBuying;
import com.quanquan.store.entity.GroupBuyingTradingRecord;
import com.quanquan.store.entity.Order;
import com.quanquan.store.entity.ShoppingKillTradingRecord;
import com.quanquan.store.repository.GroupBuyingTradingRecordRepository;
import com.quanquan.store.repository.ShoppingKillTradingRecordRepository;
import com.quanquan.store.request.*;
import com.quanquan.store.service.*;
import com.quanquan.store.shenxinpay.enitiy.request.NotifyModle;
import commond.IntegralOutPut;
import enums.ResCodeEnum;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import utils.*;
import web.response.ResultBody;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.text.DecimalFormat;
import java.util.*;

@RestController
@RequestMapping("/wxpay")
public class WxPayController extends BaseController {

    private final OrderService orderService;
    private final WxPayService wxPayService;
    private final ShoppingKillTradingRecordService shoppingKillTradingRecordService;
    private final ShoppingKillTradingRecordRepository shoppingKillTradingRecordRepository;
    private final CouponService couponService;
    private final RabbitSender rabbitSender;
    @Autowired
    private GroupBuyingTradingRecordRepository groupBuyingTradingRecordRepository;

    @Autowired
    private GroupBuyingTradingRecordService groupBuyingTradingRecordService;

    @Autowired
    public WxPayController(ShoppingKillTradingRecordService shoppingKillTradingRecordService, WxPayService wxPayService, OrderService orderService, ShoppingKillTradingRecordRepository shoppingKillTradingRecordRepository, CouponService couponService, RabbitSender rabbitSender) {
        this.shoppingKillTradingRecordService = shoppingKillTradingRecordService;
        this.wxPayService = wxPayService;
        this.orderService = orderService;
        this.shoppingKillTradingRecordRepository = shoppingKillTradingRecordRepository;
        this.couponService = couponService;
        this.rabbitSender = rabbitSender;
    }

    private static Cipher cipher = null;  //解码器
    @Value("${module-url.parkingUrl}")
    private String parkingUrl;
    @Value("${wx-pay.secert}")
    private String secert;
    @Value("${module-url.userUrl}")
    private String userUrl;

    /**
     * 微信服务器通知java后端
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_pay")
    @ResponseBody
    public Map<String, Object> wxPay(@RequestBody WxPayRequest wxPayRequest) {
        return wxPayService.wxPay(wxPayRequest);
    }

    /**
     * 生成预订单
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/create_parking_order")
    @ResponseBody
    public ResultBody createParkingOrder(@RequestBody WxPayRequest wxPayRequest) {
        if (StringUtil.isEmpty(wxPayRequest.getUserId()) || wxPayRequest.getUserId() == null) {
            return new ResultBody(ResCodeEnum.UG_PAEAMES.getCode(), ResCodeEnum.UG_PAEAMES.getMsg());
        }
        Map<String, Object> map = wxPayService.createParkingOrderOld(wxPayRequest);
        if (map == null || map.isEmpty()) {
            return new ResultBody(ResCodeEnum.FAIL.getCode(), ResCodeEnum.FAIL.getMsg());
        }
        if (map.get("msg") != null && !map.get("msg").equals("已完成订单")) {
            return new ResultBody(ResCodeEnum.FAIL.getCode(), ResCodeEnum.FAIL.getMsg(), map);
        }
        if (map.get("msg") != null && map.get("msg").equals("已完成订单")) {
            return new ResultBody(ResCodeEnum.SUCCESS.getCode(), ResCodeEnum.SUCCESS.getMsg(), map);
        }
        return new ResultBody(ResCodeEnum.CUSTOM.getCode(), ResCodeEnum.CUSTOM.getMsg(), map);
    }

    /**
     * 生成停车会员预订单
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/create_ketop_vip_order")
    @ResponseBody
    public ResultBody createKetopVipOrder(@RequestBody WxPayRequest wxPayRequest) {
        if (StringUtil.isEmpty(wxPayRequest.getUserId()) || wxPayRequest.getUserId() == null) {
            return new ResultBody(ResCodeEnum.UG_PAEAMES.getCode(), ResCodeEnum.UG_PAEAMES.getMsg());
        }
        Map<String, Object> map = wxPayService.createKetopVip(wxPayRequest);
        if (map.isEmpty()) {
            return new ResultBody(ResCodeEnum.FAIL.getCode(), ResCodeEnum.FAIL.getMsg());
        }
        if (map.get("msg") != null && !map.get("msg").equals("已完成订单")) {
            return new ResultBody(ResCodeEnum.FAIL.getCode(), ResCodeEnum.FAIL.getMsg(), map);
        }
        if (map.get("msg") != null && map.get("msg").equals("已完成订单")) {
            return new ResultBody(ResCodeEnum.SUCCESS.getCode(), ResCodeEnum.SUCCESS.getMsg(), map);
        }
        return new ResultBody(ResCodeEnum.CUSTOM.getCode(), ResCodeEnum.CUSTOM.getMsg(), map);
    }


    /**
     * 微信服务器通知java后端（秒杀）
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_notify")
    @ResponseBody
    public String wxNotify() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        String outTradeNo = (String) map.get("out_trade_no");
        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            // 验证签名是否正确
            @SuppressWarnings("unchecked")
            Map<String, String> validParams = PayUtils.paraFilter(map); // 回调验签时需要去除sign和空值参数
            String validStr = PayUtils.createLinkString(validParams);// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            String sign = PayUtils.sign(validStr, secert, "utf-8").toUpperCase();// 拼装生成服务器端验证的签名
            // String ownOrderNo = request.getParameter("ownOrderNo");//获取订单号
            ShoppingKillTradingRecord order = shoppingKillTradingRecordService.findByOrderRecord(outTradeNo);

            boolean b = shoppingKillTradingRecordService.updateRecord(outTradeNo, transactionId, order);
            if (b) {
                CouponRequest couponRequest = new CouponRequest();
                couponRequest.setId(order.getGoodId());
                couponRequest.setUserId(order.getUseId());
                couponRequest.setSendRequestType(1);
                //获取券的方式 1-后台手动推券 2-积分商城购买 3-秒杀 4-注册规则送券 5-邀请注册送券 6-消费满积分送券
                Integer getType = 3;
                couponRequest.setGetType(getType);
                couponService.sendShoppingKillCoupon(couponRequest);
            }

            Integer priceD = order.getPrice().intValue() * 100;
            String price = priceD.toString();
            // 根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
            if (sign.equals(map.get("sign"))) {
                // 通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
        return resXml;
    }


    /**
     * 团购退款
     */
    @RequestMapping("/refundNotify")
    public void refundNotify() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        System.out.println("xml......"+notityXml);
        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);
        System.out.println("map......"+map);
        String returnCode = (String) map.get("return_code");
        String req_info = (String) map.get("req_info");
        System.out.println("req_info......."+req_info);
        String xmlString = AESUtil2.decryptData(req_info);
//        System.out.println("req_info......."+s1);
        Map map1 = PayUtils.doXMLParse(xmlString);
        String out_trade_no = map1.get("out_trade_no").toString();
        System.out.println("out_trade_no......"+out_trade_no);
//        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            GroupBuyingTradingRecord order = groupBuyingTradingRecordService.findByOrderRecord(out_trade_no);
            String s = order.getTradingStatus().toString();
            if ("refunding".equals(s)) {
                order.setTradingStatus(GroupBuyingTradingRecord.TradingStatus.refund);
            }
            groupBuyingTradingRecordRepository.save(order);
        }
    }




    /**
     * 微信服务器通知java后端(团购)
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_callback")
    @ResponseBody
    public String wxCallback() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        String outTradeNo = (String) map.get("out_trade_no");
        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            // 验证签名是否正确
            @SuppressWarnings("unchecked")
            Map<String, String> validParams = PayUtils.paraFilter(map); // 回调验签时需要去除sign和空值参数
            String validStr = PayUtils.createLinkString(validParams);// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            String sign = PayUtils.sign(validStr, secert, "utf-8").toUpperCase();// 拼装生成服务器端验证的签名
            // String ownOrderNo = request.getParameter("ownOrderNo");//获取订单号
            GroupBuyingTradingRecord order = groupBuyingTradingRecordService.findByOrderRecord(outTradeNo);

            boolean b = groupBuyingTradingRecordService.updateRecord(outTradeNo, transactionId, order);

            // 根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
            if (sign.equals(map.get("sign"))) {
                // 通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
        return resXml;
    }

    /**
     * 微信服务器通知java后端
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_buy_notify")
    @ResponseBody
    public String wxBuyNotify() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        String outTradeNo = (String) map.get("out_trade_no");
        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            // 验证签名是否正确
            @SuppressWarnings("unchecked")
            Map<String, String> validParams = PayUtils.paraFilter(map); // 回调验签时需要去除sign和空值参数
            String validStr = PayUtils.createLinkString(validParams);// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            String sign = PayUtils.sign(validStr, secert, "utf-8").toUpperCase();// 拼装生成服务器端验证的签名
            // String ownOrderNo = request.getParameter("ownOrderNo");//获取订单号

            orderService.updateOrder(outTradeNo, transactionId);
            Order order = orderService.findByOrderNum(outTradeNo);
//            couponService.updateCouponCodeStatus(order.getUserId(),order.getCouponId(),order.getCount());

            Integer priceD = order.getPrice().intValue() * 100;
            String price = priceD.toString();
            // 根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
            if (sign.equals(map.get("sign"))) {
//                // 返回的金额与系统订单的金额进行比对
//                if (price == request.getParameter("payable")) {
//                    return;
//                }
                // 通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
        return resXml;
    }

    /**
     * 微信服务器通知java后端
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_parking_notify_old")
    @ResponseBody
    public void wxParkingNotifyOld() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        String outTradeNo = (String) map.get("out_trade_no");
        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            // 验证签名是否正确
            @SuppressWarnings("unchecked")
            Map<String, String> validParams = PayUtils.paraFilter(map); // 回调验签时需要去除sign和空值参数
            String validStr = PayUtils.createLinkString(validParams);// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            String sign = PayUtils.sign(validStr, secert, "utf-8").toUpperCase();// 拼装生成服务器端验证的签名

            PayParkingFeeRequest payParkingFeeRequest = new PayParkingFeeRequest();
            payParkingFeeRequest.setOrderNo(outTradeNo);
            String postJson = Request.postJson(parkingUrl + "/ketop_parking/query_by_parking_order_num", payParkingFeeRequest);

            JSONObject jsonObject = JSON.parseObject(postJson);
            if (null == jsonObject) {
                return;
            }
            Integer resCode = jsonObject.getInteger("resCode");
            KetopParkingRecordDTO data = new KetopParkingRecordDTO();
            if (0 == resCode) {
                data = jsonObject.getJSONObject("data").toJavaObject(KetopParkingRecordDTO.class);
            }
            if (data.getStatus() == 1) {
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                //同步停车数据，此项目微信支付只是微信支付，不会涉及到积分+券的部分，所以此处只对金额进行处理
                // 传给科拓的时候只需要传入金额就行，没有优惠的概念
                PayParkingFeeRequest parkingRecordRequest = new PayParkingFeeRequest();
                parkingRecordRequest.setOrderNo(outTradeNo);
                parkingRecordRequest.setTransactionId(transactionId);
                parkingRecordRequest.setAmount(data.getFee());
                parkingRecordRequest.setDiscount(0);
                parkingRecordRequest.setFreeMoney(0);
                parkingRecordRequest.setFreeTime(0);
                List<FreeDetail> freeDetails = new LinkedList<>();
                FreeDetail freeDetail = new FreeDetail();
                freeDetail.setType(0);
                freeDetail.setMoney(0);
                freeDetail.setTime(0);
                freeDetail.setCode(data.getUserId());
                freeDetails.add(freeDetail);
                parkingRecordRequest.setFreeDetail(freeDetails);
                String s = Request.postJson(parkingUrl + "/ketop_parking/pay_parking_fee", parkingRecordRequest);
                JSONObject jsonObject1 = JSONObject.parseObject(s);
                if (jsonObject1.containsKey("resCode") && jsonObject1.getInteger("resCode") == 0) {
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                } else {
                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                            + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                }
            }
            // 根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
            /*if (sign.equals(map.get("sign"))) {
                // 通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }*/
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();

    }

    /**
     * 微信服务器通知java后端
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_parking_notify")
    @ResponseBody
    public void wxParkingNotify() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        String outTradeNo = (String) map.get("out_trade_no");
        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            // 验证签名是否正确
            @SuppressWarnings("unchecked")
            Map<String, String> validParams = PayUtils.paraFilter(map); // 回调验签时需要去除sign和空值参数
            String validStr = PayUtils.createLinkString(validParams);// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            String sign = PayUtils.sign(validStr, secert, "utf-8").toUpperCase();// 拼装生成服务器端验证的签名

            PayParkingFeeRequest payParkingFeeRequest = new PayParkingFeeRequest();
            payParkingFeeRequest.setOrderNo(outTradeNo);
            String postJson = Request.postJson(parkingUrl + "/ketop_parking/query_by_parking_order_num", payParkingFeeRequest);

            JSONObject jsonObject = JSON.parseObject(postJson);
            if (null == jsonObject) {
                return;
            }
            Integer resCode = jsonObject.getInteger("resCode");
            KetopParkingRecordDTO data = new KetopParkingRecordDTO();
            if (0 == resCode) {
                data = jsonObject.getJSONObject("data").toJavaObject(KetopParkingRecordDTO.class);
            }
            Integer priceD = data.getFee();
            String price = String.valueOf(priceD);
            PayParkingFeeRequest parkingRecordRequest = new PayParkingFeeRequest();
            if (data.getStatus() == 0) {
                //含积分支付
                if (data.getIntegral() > 0) {
                    IntegralOutPut integralOutPut = new IntegralOutPut();
                    integralOutPut.setIntegralPoint(data.getIntegral().toString());
                    integralOutPut.setOrderNum(data.getOrderNo());
                    integralOutPut.setUserId(data.getUserId());
                    integralOutPut.setSource("积分抵扣停车费");
                    integralOutPut.setTradeAction(1);
                    integralOutPut.setForeignKeyId(data.getOrderNo());
                    integralOutPut.setRemark("水游城小程序停车 - " + data.getPlateNum());
                    DecimalFormat df = new DecimalFormat("0.00");
                    String str = df.format(data.getTotalFreeFee() / 100);
                    integralOutPut.setTradingContent("停车抵扣金额:" + str + "元");
                    integralOutPut.setConsumeType("parking");
                    String postJson3 = Request.postJson(userUrl + "/integral_details/check_Integral_deduct", integralOutPut);
                    JSONObject jsonObjec3 = JSON.parseObject(postJson3);
                    if (null != jsonObjec3 && jsonObjec3.getInteger("resCode") == 0) {
                        //同步停车数据
                        parkingRecordRequest.setOrderNo(outTradeNo);
                        parkingRecordRequest.setTransactionId(transactionId);
                        parkingRecordRequest.setAmount(data.getTotalFee() - data.getTotalFreeFee());
                        parkingRecordRequest.setDiscount(0);
                        parkingRecordRequest.setFreeMoney(data.getTotalFreeFee());
                        List<FreeDetail> freeDetails = new LinkedList<>();
                        FreeDetail freeDetail = new FreeDetail();
                        freeDetail.setType(0);
                        freeDetail.setMoney(data.getTotalFreeFee());
                        freeDetail.setTime(0);
                        freeDetail.setCode(data.getUserId());
                        freeDetails.add(freeDetail);
                        parkingRecordRequest.setFreeDetail(freeDetails);
                        if (data.getTotalFreeFee() > 0) {
                            Request.postJson(parkingUrl + "/ketop_parking/get_payment_recharge_old", parkingRecordRequest);
                        } else {
                            Request.postJson(parkingUrl + "/ketop_parking/pay_parking_fee_old", parkingRecordRequest);
                        }
                        //发送任务队列，完成签到任务
                        Map<String, Object> properties = new HashMap<>();
                        properties.put("userId", data.getUserId());
                        properties.put("taskType", "parking");
                        //将计算结果放到MQ队列去补充明细的余额
                        String msg = "补全积分明细余额";
                        String exchange = "task.exchange";
                        String routingKey = "task.sign";
                        rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);
                        // 通知微信服务器已经支付成功
                        resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        // 积分扣减失败
                        // TODO 退款逻辑
                        /* wxPayService.refundOrder(outTradeNo);*/
                        // 根据甲方需求，当用户积分抵扣失败的时候，不通知车场，更新订单为失败状态
                        parkingRecordRequest.setOrderNo(outTradeNo);
                        Request.postJson(parkingUrl + "/ketop_parking/update_order_fail", parkingRecordRequest);
                        resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    }
                }else{
                    //同步停车数据
                    parkingRecordRequest.setOrderNo(outTradeNo);
                    parkingRecordRequest.setTransactionId(transactionId);
                    parkingRecordRequest.setAmount(data.getTotalFee() - data.getTotalFreeFee());
                    parkingRecordRequest.setDiscount(0);
                    parkingRecordRequest.setFreeMoney(data.getTotalFreeFee());
                    List<FreeDetail> freeDetails = new LinkedList<>();
                    FreeDetail freeDetail = new FreeDetail();
                    freeDetail.setType(0);
                    freeDetail.setMoney(data.getTotalFreeFee());
                    freeDetail.setTime(0);
                    freeDetail.setCode(data.getUserId());
                    freeDetails.add(freeDetail);
                    parkingRecordRequest.setFreeDetail(freeDetails);
                    if (data.getTotalFreeFee() > 0) {
                        Request.postJson(parkingUrl + "/ketop_parking/get_payment_recharge_old", parkingRecordRequest);
                    } else {
                        Request.postJson(parkingUrl + "/ketop_parking/pay_parking_fee_old", parkingRecordRequest);
                    }
                    //发送任务队列，完成签到任务
                    Map<String, Object> properties = new HashMap<>();
                    properties.put("userId", data.getUserId());
                    properties.put("taskType", "parking");
                    //将计算结果放到MQ队列去补充明细的余额
                    String msg = "补全积分明细余额";
                    String exchange = "task.exchange";
                    String routingKey = "task.sign";
                    rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);
                    // 通知微信服务器已经支付成功
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                }
            }else{
                // 通知微信服务器已经支付成功(重复通知时)
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
            // 根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }


    /**
     * 微信服务器通知java后端
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(path = "/payNotify", method = RequestMethod.POST)
    public String payNotify(@RequestBody NotifyModle notifyRequest) {
        if (!"S".equalsIgnoreCase(notifyRequest.getTrade_status())) {
            return "ERROR";
        }
        String outTradeNo = notifyRequest.getOut_order_id();
        String transactionId = notifyRequest.getChnl_order_id();

        PayParkingFeeRequest payParkingFeeRequest = new PayParkingFeeRequest();
        payParkingFeeRequest.setOrderNo(outTradeNo);
        String postJson = Request.postJson(parkingUrl + "/ketop_parking/query_by_parking_order_num", payParkingFeeRequest);

        JSONObject jsonObject = JSON.parseObject(postJson);
        if (null == jsonObject) {
            return "ERROR";
        }
        Integer resCode = jsonObject.getInteger("resCode");
        KetopParkingRecordDTO data = new KetopParkingRecordDTO();
        if (0 == resCode) {
            data = jsonObject.getJSONObject("data").toJavaObject(KetopParkingRecordDTO.class);
        }
        //同步积分
        if (data.getIntegral() > 0) {
            IntegralOutPut integralOutPut = new IntegralOutPut();
            integralOutPut.setIntegralPoint(data.getIntegral().toString());
            integralOutPut.setOrderNum(data.getOrderNo());
            integralOutPut.setUserId(data.getUserId());
            integralOutPut.setSource("积分抵扣停车费");
            integralOutPut.setTradeAction(1);
            integralOutPut.setConsumeType("parking");
            integralOutPut.setForeignKeyId(data.getOrderNo());
            DecimalFormat df = new DecimalFormat("0.00");
            String str = df.format(data.getTotalFreeFee() / 100);
            integralOutPut.setTradingContent("停车抵扣金额:" + str + "元");

            //将计算结果放到MQ队列去补充明细的余额
            String exchange = "integral.exchange";
            String routingKey = "integral.store";
            rabbitSender.sendMessageToMQ(integralOutPut, null, exchange, routingKey);
        }
        //核销停车券

        Integer priceD = data.getTotalFee() - data.getTotalFreeFee();
        String price = String.valueOf(priceD.intValue());
        //同步停车数据
        PayParkingFeeRequest parkingRecordRequest = new PayParkingFeeRequest();
        parkingRecordRequest.setOrderNo(outTradeNo);
        parkingRecordRequest.setTransactionId(transactionId);
        parkingRecordRequest.setAmount(data.getTotalFee() - data.getTotalFreeFee());
        parkingRecordRequest.setDiscount(0);
        parkingRecordRequest.setFreeMoney(data.getTotalFreeFee());
        parkingRecordRequest.setFreeTime(0);
        List<FreeDetail> freeDetails = new LinkedList<>();
        FreeDetail freeDetail = new FreeDetail();
        freeDetail.setType(0);
        freeDetail.setMoney(data.getTotalFreeFee());
        freeDetail.setTime(0);
        freeDetail.setCode(data.getUserId());
        freeDetails.add(freeDetail);
        parkingRecordRequest.setFreeDetail(freeDetails);
        if (data.getTotalFreeFee() > 0) {
            Request.postJson(parkingUrl + "/ketop_parking/get_payment_recharge", parkingRecordRequest);
        } else {
            Request.postJson(parkingUrl + "/ketop_parking/pay_parking_fee", parkingRecordRequest);
        }
        System.out.println("支付宝 支付回调数据结束");
        return "SUCCESS";
    }


    /**
     * 微信服务器通知java后端（科拓vip）
     *
     * @param
     * @param
     * @throws Exception
     */
    @RequestMapping(value = "/wx_ketop_vip_notify")
    @ResponseBody
    public String wxKetopVipNotify() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        // sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        @SuppressWarnings("rawtypes")
        Map map = PayUtils.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        String outTradeNo = (String) map.get("out_trade_no");
        String transactionId = (String) map.get("transaction_id");
        if ("SUCCESS".equals(returnCode)) {
            // 验证签名是否正确
            @SuppressWarnings("unchecked")
            Map<String, String> validParams = PayUtils.paraFilter(map); // 回调验签时需要去除sign和空值参数
            String validStr = PayUtils.createLinkString(validParams);// 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
            String sign = PayUtils.sign(validStr, secert, "utf-8").toUpperCase();// 拼装生成服务器端验证的签名

            KetopVipRequest payParkingFeeRequest = new KetopVipRequest();
            payParkingFeeRequest.setOrderNo(outTradeNo);
            String postJson = Request.postJson(parkingUrl + "/ketop_vip/get_order_by_order_no", payParkingFeeRequest);

            JSONObject jsonObject = JSON.parseObject(postJson);
            if (null == jsonObject) {
                return null;
            }
            String price = "";
            Integer resCode = jsonObject.getInteger("resCode");
            KetopVipDTO data;
            if (0 == resCode) {
                data = jsonObject.getJSONObject("data").toJavaObject(KetopVipDTO.class);
                Integer priceD = data.getFee();
                price = String.valueOf(priceD.intValue());
                Request.postJson(parkingUrl + "/ketop_vip/update_ketop_vip", payParkingFeeRequest);

            }
            // 根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
            if (sign.equals(map.get("sign"))) {
                // 返回的金额与系统订单的金额进行比对
//                if (price == request.getParameter("payable")) {
//                    return;
//                }
                // 通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
        return resXml;
    }


    @RequestMapping(value = "/test")
    @ResponseBody
    public void test() throws Exception {
        wxPayService.refundOrder("8ccb7deb0e584dba943bba52e3b4436a");
    }

}
